跳到主要内容

Mapreduce 作业失败 ⭐️

在实际情况中,用户代码错误、进程崩溃和机器故障是常见的问题。Hadoop作为一个分布式系统,具有处理这些故障的能力,并且能够帮助用户成功完成作业。下面是需要考虑的各个实体的失败情况:

  • 任务(Tasks):在MapReduce作业中,任务可能会失败,例如由于程序错误、资源不足或数据丢失。Hadoop能够检测到任务的失败,并根据失败情况进行相应的处理,如重新尝试任务或将失败的任务分配给其他可用的节点。
  • Application Master(应用程序主管):Application Master负责协调作业的执行,并与资源管理器进行通信。如果Application Master失败,资源管理器会重新启动它,并将作业状态恢复到失败之前的状态。这样可以确保作业能够继续执行。
  • 节点管理器(NodeManager):节点管理器负责管理集群中的每个节点,并监控任务的运行状态。如果节点管理器失败,资源管理器会重新分配任务到其他可用的节点,并启动新的节点管理器来接管失败的节点的工作。
  • 资源管理器(ResourceManager):资源管理器是整个集群的主要组件,负责资源分配和作业调度。如果资源管理器失败,Hadoop会使用ZooKeeper等机制来实现高可用性,以确保集群能够继续正常运行。

1.任务运行失败

在MapReduce中,任务失败的情况有以下几种处理方式:

  • 用户代码抛出异常:如果任务中的用户代码抛出异常,任务的JVM会向其父Application Master发送错误报告,并将任务标记为失败。容器会被释放以便为其他任务释放资源。
  • Streaming任务退出:对于Streaming任务,如果Streaming进程以非零退出代码退出,则任务会被标记为失败。
  • 任务JVM突然退出:如果任务的JVM突然退出,例如由于JVM软件缺陷,节点管理器会注意到进程已经退出,并通知Application Master将任务标记为失败。
  • 任务挂起:如果Application Master在一段时间内没有收到任务的进度更新,会将任务标记为失败。超时时间可以通过mapreduce.task.timeout属性进行设置,默认为10分钟。

一旦任务被标记为失败,Application Master会重新调度任务的执行。它会尝试避免在之前失败过的节点管理器上重新调度任务。另外,如果一个任务失败超过4次,将不再进行重试。这个最大尝试次数可以通过下面两个属性进行配置。默认情况下,如果任何任务失败次数大于4次,整个作业将失败。

  • map.maxattempts
  • reduce.maxattempts

对于一些应用程序,我们可能不希望一旦有少数几个任务失败就中止整个作业的运行。可以通过设置下面两个参数来控制允许任务失败的最大百分比来避免作业失败。

  • map.failures.maxpercent
  • reduce.failures.maxpercent

任务尝试可以被中止,这与任务失败不同。任务尝试可以被中止,因为它是一个推测副本或所在的节点管理器失败。被中止的任务尝试不会计入任务的尝试次数。

2.application master 运行失败

在YARN中,应用程序在运行失败时有几次尝试的机会,就像MapReduce任务在遇到硬件或网络故障时要进行几次尝试一样。运行MapReduce应用程序的Application Master的最大尝试次数由下面参数控制,默认值为2。如果MapReduce Application Master失败两次,将不再进行尝试,作业将失败。

  • am.max-attempts

需要注意的是:

YARN对集群上运行的YARN应用程序的Application Master的最大尝试次数也进行了限制,单个应用程序不可以超过这个限制。该限制由下面参数控制,默认值为2。如果想增加MapReduce Application Master的尝试次数,必须增加集群上YARN的设置。

  • resourcemanager.am.max-attempts

在应用程序失败后的恢复过程如下:

Application Master会向资源管理器发送周期性的心跳。当Application Master失败时,资源管理器会检测到该失败,并在一个新的容器中启动一个新的Application Master实例(由节点管理器管理)。对于MapReduce Application Master,它将使用作业历史信息来恢复失败应用程序中运行任务的状态,避免重新运行。默认情况下,恢复功能是开启的(默认值为true),可以通过下面参数来控制。

  • app.mapreduce.am.job.recovery.enable

MapReduce客户端会轮询Application Master以获取进度报告。但是,如果Application Master运行失败,客户端需要定位新的实例。在作业初始化阶段,客户端会向资源管理器询问并缓存Application Master的地址,这样每次需要查询Application Master时就不必重新加载资源管理器。但是,如果Application Master运行失败,客户端在发出状态更新请求时可能会超时,然后会向资源管理器请求新的Application Master的地址。这个过程对用户是透明的。

3.节点管理器(nodemanager)运行失败

如果nodemanager由于崩溃(硬件故障等问题)或运行缓慢而失败,它将停止向资源管理器(resourcemanager)发送心跳信息(或发送频率很低)。resourcemanager在下面参数设定的时间(默认为10分钟)内没有收到nodemanager的心跳信息,将停止此nodemanager,并将其从节点池中移除以调度其他可用的容器。

  • resourcemanager.nm.liveness-monitor.expiry-interval-ms

在失败的节点上运行的所有任务或application master都会按照前面描述的机制进行恢复。已经成功完成的map任务,如果它们属于未完成的作业,application master会将这些任务重新运行。这是因为这些任务的中间输出可能存储在失败的节点管理器的本地文件系统中,导致reduce任务可能无法访问这些输出。

需要注意的是:

如果一个nodemanager上的任务失败次数过高,即使nodemanager本身并没有失败,application master也会将该nodemanager加入黑名单。对于MapReduce作业,如果一个节点管理器上有超过三个任务失败,application master会尽量将任务调度到其他节点上,避免继续在该节点上执行任务。用户可以通过下面参数控制在一个nodemanager上允许的任务失败次数。

  • job.maxtaskfailures.per.tracker

4.资源管理器运行失败

单点模式下的Yarn集群,resourcemanager有很大的失败风险,这种失败会导致作业和任务容器将无法启动,所有正在运行的作业都将失败且无法恢复。解决的方式是实现双机热备HA,如果主resourcemanager失败,备份resourcemanager将接管,并且客户端不会感知到明显的中断

当出现resourcemanager失败时,备份resourcemanager接管之后,它从状态存储区中读取应用程序的信息,然后为集群中运行的所有应用程序重启 application  master。

HA模式下,客户端会根据配置以轮询(round-robin) 方式试图连接每一个resourcemanager,直到找到主resourcemanager。如果主resourcemanager故障,他们将再次尝试直到备份resourcemanager变成主resourcemanager。